home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Directorty Opus 5 - Magellan 2
/
Opus 5 - Magellan 2.iso
/
Archiv
/
OpusSDK.lha
/
opussdk
/
examples
/
iconclock
/
iconclock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-05
|
14KB
|
695 lines
#include "iconclock.h"
// Define the version string here
static char *version="$VER: iconclock.module 55.0 (15.08.96)";
// Main entry point
int __asm __saveds L_Module_Entry(
register __a0 char *args,
register __a1 struct Screen *screen,
register __a2 IPCData *ipc,
register __a3 IPCData *main_ipc,
register __d0 ULONG mod_id,
register __d1 EXT_FUNC(func_callback))
{
iconclock_data *data;
IPCData *clock_ipc;
// See if we're already running; return if we are
if (FindSemaphore(NAME_ICONCLOCK)) return 1;
// Allocate data
if (data=AllocVec(sizeof(iconclock_data),MEMF_CLEAR))
{
// Store A4 and library bases
data->a4=getreg(REG_A4);
data->library=DOpusBase;
data->module=(struct Library *)getreg(REG_A6);
data->main_ipc=main_ipc;
// Store initial screen
data->screen=screen;
data->pen=-1;
// Launch process
if (!(IPC_Launch(
0,
&clock_ipc,
NAME_ICONCLOCK,
(ULONG)icon_clock,
4000,
(ULONG)data,
DOSBase))) FreeVec(data);
}
// No process?
if (!clock_ipc) return 0;
return 1;
}
// Icon clock process
void __saveds icon_clock(void)
{
IPCData *ipc;
IPCMessage *msg;
DOpusNotify *nmsg;
struct AppMessage *amsg;
struct Library *DOpusBase;
iconclock_data *data;
BOOL quit=0,visible=1;
// Get dopus library
if (!(DOpusBase=(struct Library *)FindName(&((struct ExecBase *)*((ULONG *)4))->LibList,"dopus5.library")))
return;
// Do startup
ipc=IPC_ProcStartup((ULONG *)&data,iconclock_startup);
// Fix A4 so we can access global data in the module (eg library bases)
putreg(REG_A4,data->a4);
// Failed?
if (!ipc)
{
iconclock_cleanup(data);
return;
}
// Got a screen?
if (data->screen)
{
struct Screen *scr=data->screen;
// Initialise clock for this screen
data->screen=0;
iconclock_init(data,scr);
}
// Event loop
FOREVER
{
// Timer returned?
if (CheckTimer(data->timer))
{
// Update the time if visible
if (visible)
{
// Show time
iconclock_show(data);
}
// Restart timer
StartTimer(data->timer,0,900000);
}
// IPC messages?
while (msg=(IPCMessage *)GetMsg(ipc->command_port))
{
// We don't do anything with them at this stage
IPC_Reply(msg);
}
// Notify messages from Opus?
while (nmsg=(DOpusNotify *)GetMsg(data->notify_port))
{
// Opus has Quit?
if (nmsg->dn_Type&DN_OPUS_QUIT) quit=1;
// Opus has been hidden?
else
if (nmsg->dn_Type&DN_OPUS_HIDE)
{
// Made invisible
iconclock_init(data,0);
visible=0;
}
// Opus has been revealed
else
if (nmsg->dn_Type&DN_OPUS_SHOW)
{
// Screen changed?
if (data->screen!=((struct Window *)nmsg->dn_Data)->WScreen)
{
// Just made visible
iconclock_init(data,((struct Window *)nmsg->dn_Data)->WScreen);
}
visible=1;
}
// Reply to the message
ReplyFreeMsg((struct Message *)nmsg);
}
// About Requester open?
if (data->about)
{
// Handle requester
if (SysReqHandler(data->about,0,0)>=0)
{
// Close requester
FreeSysRequest(data->about);
data->about=0;
}
}
// Check quit flag
if (quit) break;
// AppMessages?
while (amsg=(struct AppMessage *)GetMsg(data->app_port))
{
// SnapShot?
if (amsg->am_Type==MTYPE_APPSNAPSHOT)
{
struct AppSnapshotMsg *asm;
// Get SnapShot message pointer
asm=(struct AppSnapshotMsg *)amsg;
// Menu operation?
if (asm->flags&APPSNAPF_MENU)
{
// Help?
if (asm->flags&APPSNAPF_HELP)
{
// Send help request
if (data->main_ipc)
IPC_Command(data->main_ipc,IPC_HELP,(1<<31),"Icon Clock",0,REPLY_NO_PORT);
}
// Colour?
else
if (asm->id==0)
{
struct Screen *screen;
// Toggle colour state
data->colour=1-data->colour;
// Set menu state
SetAppIconMenuState(data->appicon,0,data->colour);
// Save screen
screen=data->screen;
// Close and re-open
iconclock_init(data,0);
iconclock_init(data,screen);
}
}
// Close?
else
if (asm->flags&APPSNAPF_CLOSE) quit=1;
// Info?
else
if (asm->flags&APPSNAPF_INFO)
{
// Show info
iconclock_info(data);
}
// Otherwise
else
{
// Unsnapshot?
if (asm->flags&APPSNAPF_UNSNAPSHOT)
{
// Reinitialise position
data->icon_x=NO_ICON_POSITION;
data->icon_y=NO_ICON_POSITION;
}
// Store position
else
{
data->icon_x=asm->position_x;
data->icon_y=asm->position_y;
}
// Build environment variable
sprintf(
data->buffer,
"%d/%d/%d\n",
data->icon_x,
data->icon_y,
data->colour);
// Set environment variable
SetEnv(ENV_ICONCLOCK,data->buffer,TRUE);
}
}
// Double-click?
else
if (amsg->am_Type==MTYPE_APPICON &&
amsg->am_NumArgs==0)
{
// Launch date prefs
LaunchWB("sys:prefs/time",0,0);
}
// Reply to message
ReplyMsg((struct Message *)amsg);
}
// Check quit flag
if (quit) break;
// Wait for event
Wait( 1<<ipc->command_port->mp_SigBit|
1<<data->notify_port->mp_SigBit|
1<<data->timer->port->mp_SigBit|
1<<data->app_port->mp_SigBit|
((data->about)?(1<<data->about->UserPort->mp_SigBit):0));
}
// Decrement open count so we can be flushed again
--data->module->lib_OpenCnt;
// Cleanup
iconclock_cleanup(data);
}
// Startup code, called by IPC_ProcStartup()
ULONG __asm __saveds iconclock_startup(
register __a0 IPCData *ipc,
register __a1 iconclock_data *data)
{
struct Library *DOpusBase;
// Fix A4
putreg(REG_A4,data->a4);
// Store IPC
data->ipc=ipc;
// Get library
DOpusBase=data->library;
// Initialise data
data->icon_x=NO_ICON_POSITION;
data->icon_y=NO_ICON_POSITION;
// Initialise Semaphore
data->sem.sem.ss_Link.ln_Name=NAME_ICONCLOCK;
data->sem.ipc=ipc;
AddSemaphore((struct SignalSemaphore *)&data->sem);
// Create message ports
if (!(data->notify_port=CreateMsgPort()) ||
!(data->app_port=CreateMsgPort()))
return 0;
// Create timer
if (!(data->timer=AllocTimer(UNIT_VBLANK,0)))
return 0;
// Add notify request
if (!(data->notify_req=
AddNotifyRequest(
DN_OPUS_QUIT|DN_OPUS_HIDE|DN_OPUS_SHOW,
0,
data->notify_port))) return 0;
// Get environment variable
if (GetVar(ENV_ICONCLOCK,data->buffer,sizeof(data->buffer),GVF_GLOBAL_ONLY)>0)
{
char *ptr;
// Get buffer pointer
ptr=data->buffer;
// Get position
read_parse_set(&ptr,&data->icon_x);
read_parse_set(&ptr,&data->icon_y);
read_parse_set(&ptr,&data->colour);
}
// Bump library open count so we don't get flushed
++data->module->lib_OpenCnt;
// Start timer
StartTimer(data->timer,0,900000);
return 1;
}
// Cleanup
void iconclock_cleanup(iconclock_data *data)
{
if (data)
{
struct Message *msg;
// Free screen lock
iconclock_init(data,0);
// Remove notify request
RemoveNotifyRequest(data->notify_req);
// Close requester
FreeSysRequest(data->about);
data->about=0;
// Flush message ports
if (data->notify_port)
{
while (msg=GetMsg(data->notify_port))
ReplyFreeMsg(msg);
}
if (data->app_port)
{
while (msg=GetMsg(data->app_port))
ReplyFreeMsg(msg);
}
// Delete message ports
DeleteMsgPort(data->notify_port);
DeleteMsgPort(data->app_port);
// Free timer
FreeTimer(data->timer);
// Remove Semaphore
RemSemaphore((struct SignalSemaphore *)&data->sem);
// Free data
IPC_Free(data->ipc);
FreeVec(data);
}
}
// Show current time
void iconclock_show(iconclock_data *data)
{
struct DateStamp date;
unsigned long hour,minute,second;
short time[4],colon,x,y=2,a;
long flags=CAIF_RENDER|CAIF_SELECT;
// Open?
if (!data->screen) return;
// Get current time
DateStamp(&date);
// Get hours and minutes and seconds
hour=DivideU(date.ds_Minute,60,&minute,UtilityBase);
second=UDivMod32(date.ds_Tick,TICKS_PER_SECOND);
// Get colon we need (either upper or lower half flashing)
if ((second%2)==0) colon=0;
else
if (second<30) colon=1;
else
colon=2;
// Get numerals we need for hour
if (hour>9)
{
if (hour>19)
{
time[0]=2;
time[1]=hour-20;
}
else
{
time[0]=1;
time[1]=hour-10;
}
}
else
{
time[0]=-1;
time[1]=hour;
}
// Get numerals we need for minute
time[2]=0;
while (minute>9)
{
++time[2];
minute-=10;
}
time[3]=minute;
// Draw digits
for (a=0,x=2;a<4;a++,x+=NUMERAL_WIDTH+2)
{
// Valid number?
if (time[a]>-1)
{
// Draw number
BltTemplate(
(char *)numeral_data[time[a]],
0,2,
&data->clock_rp,
x,y,
NUMERAL_WIDTH,NUMERAL_HEIGHT);
}
// Erase area
else
{
// Save fg pen
short fg=data->clock_rp.FgPen;
// Set bg pen
SetAPen(&data->clock_rp,data->clock_rp.BgPen);
// Erase it
RectFill(
&data->clock_rp,
x,y,
x+NUMERAL_WIDTH-1,
y+NUMERAL_HEIGHT-1);
// Restore pen
SetAPen(&data->clock_rp,fg);
}
// Time for the colon?
if (a==1)
{
// Draw colon
BltTemplate(
(char *)colon_data[colon],
0,2,
&data->clock_rp,
x+NUMERAL_WIDTH+1,y,
COLON_WIDTH,COLON_HEIGHT);
// Bump x position
x+=COLON_WIDTH;
}
}
// Day different?
if (date.ds_Days!=data->day)
{
struct DateTime dt;
// Fill out dt
dt.dat_Stamp=date;
dt.dat_Format=FORMAT_DOS;
dt.dat_Flags=0;
dt.dat_StrDay=0;
dt.dat_StrDate=data->date_buffer;
dt.dat_StrTime=0;
// Get date string
DateToStr(&dt);
flags|=CAIF_TITLE;
}
// Update image
ChangeAppIcon(data->appicon,&data->clock_image,&data->clock_image,data->date_buffer,flags);
}
// Parse number out of string, leave pointer at one character after end of number
void read_parse_set(char **ptr,long *val)
{
// Digit?
if (isdigit(*(*ptr)))
{
*val=atoi(*ptr);
while (*(*ptr) && isdigit(*(*ptr))) ++*ptr;
++*ptr;
}
}
// Initialise screen stuff
void iconclock_init(iconclock_data *data,struct Screen *screen)
{
// Got a screen locked?
if (data->screen)
{
// Free pen
if (data->pen>-1)
{
ReleasePen(data->screen->ViewPort.ColorMap,data->pen);
data->pen=-1;
}
// Unlock it
UnlockPubScreen(0,data->screen);
data->screen=0;
// Remove AppIcon
if (data->appicon) RemoveAppIcon(data->appicon);
data->appicon=0;
// Free bitmap
FreeVec(data->clock_image.ImageData);
data->clock_image.ImageData=0;
}
// No new screen?
if (!screen) return;
// Try to lock screen
if (FindPubScreen(screen,TRUE))
{
short depth=1;
// Store pointer
data->screen=screen;
// Under 39 grab a pen
if (GfxBase->lib_Version>=39 && data->colour)
{
// Allocate pen
if ((data->pen=ObtainPen(
screen->ViewPort.ColorMap,
-1,
0,0xffffffff,0,
PENF_EXCLUSIVE))>-1)
{
// Set colour
SetRGB32(&screen->ViewPort,data->pen,0,0xffffffff,0);
// Get depth we need
for (depth=1;depth<=8;depth++)
if (1<<depth>data->pen) break;
}
}
// Initialise clock bitmap
InitBitMap(&data->clock_bm,depth,CLOCK_WIDTH,CLOCK_HEIGHT);
// Allocate clock bitmap
if (data->clock_image.ImageData=
(USHORT *)AllocVec(RASSIZE(CLOCK_WIDTH,CLOCK_HEIGHT)*depth,MEMF_CHIP|MEMF_CLEAR))
{
struct TagItem tags[7];
USHORT *ptr;
short a;
// Get bitmap pointers
ptr=data->clock_image.ImageData;
for (a=0;a<depth;a++)
{
data->clock_bm.Planes[a]=(PLANEPTR)ptr;
ptr+=((CLOCK_WIDTH+15)>>4)*CLOCK_HEIGHT;
}
// Initialise rastport
InitRastPort(&data->clock_rp);
data->clock_rp.BitMap=&data->clock_bm;
SetDrMd(&data->clock_rp,JAM2);
// Fill in image
data->clock_image.Width=CLOCK_WIDTH;
data->clock_image.Height=CLOCK_HEIGHT;
data->clock_image.Depth=depth;
data->clock_image.PlanePick=(1<<depth)-1;
// Fill out fake DiskObject
data->clock_icon.do_Gadget.Width=CLOCK_WIDTH;
data->clock_icon.do_Gadget.Height=CLOCK_HEIGHT;
data->clock_icon.do_Gadget.Flags=GFLG_GADGHIMAGE;
data->clock_icon.do_Gadget.GadgetRender=&data->clock_image;
data->clock_icon.do_Gadget.SelectRender=&data->clock_image;
data->clock_icon.do_CurrentX=data->icon_x;
data->clock_icon.do_CurrentY=data->icon_y;
// AppIcon tags
tags[0].ti_Tag=DAE_SnapShot;
tags[0].ti_Data=1;
tags[1].ti_Tag=DAE_Close;
tags[1].ti_Data=2;
tags[2].ti_Tag=DAE_Local;
tags[2].ti_Data=1;
tags[3].ti_Tag=DAE_Info;
tags[3].ti_Data=1;
// Under 39 we can use colour
if (GfxBase->lib_Version>=39)
{
tags[4].ti_Tag=(data->pen>-1)?DAE_Background:TAG_IGNORE;
tags[4].ti_Data=1;
tags[5].ti_Tag=(data->colour)?DAE_ToggleMenuSel:DAE_ToggleMenu;
tags[5].ti_Data=(ULONG)DOpusGetString(locale,MSG_ICONCLOCK_COLOUR);
tags[6].ti_Tag=TAG_END;
}
else tags[4].ti_Tag=TAG_END;
// Add AppIcon
if (data->appicon=AddAppIconA(0,0,NAME_ICONCLOCK,data->app_port,0,&data->clock_icon,tags))
{
// If we have a pen, fill background
if (data->pen>-1) SetRast(&data->clock_rp,1);
// Set pen for clock
SetAPen(&data->clock_rp,(data->pen>-1)?data->pen:1);
SetBPen(&data->clock_rp,(data->pen>-1)?1:0);
// Show clock
iconclock_show(data);
}
}
// Failed?
if (!data->appicon)
{
// Free stuff (this is a bit recursive)
iconclock_init(data,0);
}
}
}
// Show info window
void iconclock_info(iconclock_data *data)
{
struct EasyStruct easy;
// Window open?
if (data->about)
{
WindowToFront(data->about);
ActivateWindow(data->about);
return;
}
// Fill out easy struct
easy.es_StructSize=sizeof(easy);
easy.es_Flags=0;
easy.es_Title=DOpusGetString(locale,MSG_ICONCLOCK_TITLE);
easy.es_TextFormat="Directory Opus 5 Icon Clock\nv55.0 (15.08.96)\n\n© 1996 Jonathan Potter";
easy.es_GadgetFormat=DOpusGetString(locale,MSG_OK);
// Open requester
data->about=BuildEasyRequestArgs(data->screen->FirstWindow,&easy,0,0);
}